<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8" />
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
  <title>HTML5 调用摄像头</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      text-align: center;
      margin: 0;
      padding: 20px;
      background-color: #f5f5f5;
    }
    h1 {
      color: #333;
    }
    #video {
      width: 100%;
      max-width: 400px;
      border: 2px solid #007bff;
      border-radius: 10px;
      margin: 15px auto;
      display: block;
      background-color: #000;
    }
    #canvas {
      display: none;
    }
    .btn {
      padding: 12px 24px;
      margin: 10px;
      font-size: 16px;
      border: none;
      border-radius: 8px;
      color: white;
      cursor: pointer;
      background-color: #007bff;
    }
    .btn:disabled {
      background-color: #ccc;
      cursor: not-allowed;
    }
    .btn-danger {
      background-color: #dc3545;
    }
    .btn-success {
      background-color: #28a745;
    }
    #status {
      margin: 15px 0;
      color: #d9534f;
      font-weight: bold;
    }
    .hidden {
      display: none !important;
    }
  </style>
</head>
<body>

  <h1>📷 调用摄像头</h1>
  
  <p>点击“开始摄像头”以预览画面</p>
  
  <video id="video" autoplay playsinline></video>
  <canvas id="canvas"></canvas>

  <div id="controls">
    <button id="startBtn" class="btn btn-success">开始摄像头</button>
    <button id="takePhotoBtn" class="btn btn-primary" disabled>拍照</button>
    <button id="stopBtn" class="btn btn-danger" disabled>停止</button>
  </div>

  <div id="status">等待操作...</div>

  <script>
    // 获取 DOM 元素
    const video = document.getElementById('video');
    const canvas = document.getElementById('canvas');
    const startBtn = document.getElementById('startBtn');
    const takePhotoBtn = document.getElementById('takePhotoBtn');
    const stopBtn = document.getElementById('stopBtn');
    const status = document.getElementById('status');

    let stream = null;

    // 检查浏览器是否支持 mediaDevices
    function hasGetUserMedia() {
      return !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia);
    }

    if (!hasGetUserMedia()) {
      status.textContent = '❌ 你的浏览器不支持 getUserMedia API';
      startBtn.disabled = true;
    }

    // 开始摄像头
    async function startCamera() {
      status.textContent = '正在请求摄像头权限...';
      try {
        // 请求摄像头和麦克风（可选）
        const constraints = {
          video: {
            facingMode: 'environment' // 优先使用后置摄像头
            // facingMode: 'user'     // 使用前置摄像头
          },
          audio: false // 根据需要决定是否开启麦克风
        };

        stream = await navigator.mediaDevices.getUserMedia(constraints);
        
        video.srcObject = stream;
        status.textContent = '✅ 摄像头已启动';

        // 更新按钮状态
        startBtn.disabled = true;
        takePhotoBtn.disabled = false;
        stopBtn.disabled = false;

      } catch (err) {
        console.error('无法访问摄像头:', err);
        handleCameraError(err);
      }
    }

    // 处理摄像头错误
    function handleCameraError(err) {
      let msg = '未知错误';
      switch(err.name) {
        case 'NotAllowedError':
          msg = '❌ 用户拒绝了摄像头权限请求';
          break;
        case 'NotFoundError':
          msg = '❌ 未找到摄像头设备';
          break;
        case 'NotReadableError':
          msg = '❌ 摄像头被占用或硬件故障';
          break;
        case 'TypeError':
          msg = '❌ 未选择视频源';
          break;
        case 'OverconstrainedError':
          msg = '❌ 指定的视频约束不被支持';
          break;
        default:
          msg = `❌ ${err.name}: ${err.message}`;
      }
      status.textContent = msg;
    }

    // 拍照
    function takePhoto() {
      if (!stream) return;

      const ctx = canvas.getContext('2d');
      canvas.width = video.videoWidth;
      canvas.height = video.videoHeight;
      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

      // 将图片转为 base64 数据 URL
      const dataURL = canvas.toDataURL('image/jpeg', 0.8);
      
      // 在这里你可以：
      // 1. 显示图片
      // 2. 上传到服务器
      // 3. 通过 JSBridge 传给 Android/iOS 原生代码
      alert('📸 拍照成功！图片已生成（Base64）');
      console.log('Photo Data URL:', dataURL.substring(0, 50) + '...');

      // 示例：通过 JSBridge 发送给 Android
      // if (window.AndroidBridge) {
      //   window.AndroidBridge.receivePhoto(dataURL);
      // }
    }

    // 停止摄像头
    function stopCamera() {
      if (stream) {
        stream.getTracks().forEach(track => track.stop());
        stream = null;
      }
      video.srcObject = null;
      status.textContent = '🛑 摄像头已停止';
      
      startBtn.disabled = false;
      takePhotoBtn.disabled = true;
      stopBtn.disabled = true;
    }

    // 绑定事件
    startBtn.addEventListener('click', startCamera);
    takePhotoBtn.addEventListener('click', takePhoto);
    stopBtn.addEventListener('click', stopCamera);

    // 页面卸载时停止摄像头
    window.addEventListener('beforeunload', () => {
      if (stream) {
        stream.getTracks().forEach(track => track.stop());
      }
    });
  </script>

</body>
</html>